#ifndef DB_H
#define DB_H

#include <QObject>
#include <QtSql/QSqlDatabase>
#include <QStringList>
#include <QSqlQueryModel>
#include <QList>
#include <QPointF>
#include <QVariant>
#include "config/config.h"

#define NO_FLAG 0x00
#define INSERT_MULTIPLE 0x01
#define UPDATE_BY_LIST_INDEX    0x03

#define DB_MYSQL_USERNAME_CFG_VAR   "DB_MYSQL_USER"
#define DB_MYSQL_PASS_CFG_VAR   "DB_MYSQL_PASS"

#define USE_MYSQL

#ifndef USE_MYSQL
    #define USE_SQLITE
    //#define QUOTE   QString("'")
    #define PRIM_KEY    QString("ID INTEGER PRIMARY KEY")

#endif

#ifdef USE_MYSQL
    #define PRIM_KEY    QString("ID INTEGER AUTO_INCREMENT PRIMARY KEY")
    //#define QUOTE   QString("`")
#endif

class DB
{
   // Q_OBJECT
public:
    explicit DB(QObject *parent = 0);
    explicit DB(QSqlDatabase& other,QObject *parent=0);
    explicit DB(const QString& name,Config* cfg=0,QObject *parent=0);
    ~DB();
    QSqlDatabase getDatabase();
    void setDatabase(const QSqlDatabase& other);

    bool addTable(const QString& name,const QStringList& fields);
    bool addValues(const QString& tablename,const QStringList& fields,const QStringList& vals,int flag=NO_FLAG);
    bool addValues(const QString& tablename,const QString& field,const QStringList& vals);
    bool addValues(const QString &tablename, const QStringList &fields, const QList<QStringList> &vals);
    bool addValues(const QString &tablename, const QStringList &fields, const QList<qreal> &vals);
    bool addValues(const QString &tablename, const QMap<QString,QVariant>& fieldVals);
    //TODO:
    bool updateValues(const QString& tablename,const QString& field,const QStringList& vals,int flag);
    bool updateValue(const QString& tableName,const QString& field,const QString& value,const QString& whereClause);

    void getColumn(QList<qreal>*, const QString&,const QString&,bool);         //mit virtual?
    void getColumnPairs(QList<QPointF>*,const QString&,const QString&,const QString&,bool);    //saves pairs of values from two columns in a list
    void getColumn(QStringList*, const QString &, const QString &, bool);

    QList<QMap<QString, QVariant> > getInnerJoinValues(const QString& table1,const QString& table2,const QString& table1Key,const QString& table2Key,const QStringList& fields);

    QMap<QString,QVariant> getRow(const QString& table,const QStringList& valFields,const QString& whereClause);
    QList<QMap<QString,QVariant> > getAllRows(const QString& table,const QStringList &valFields);

    QVariant getValue(const QString& table,const QString& valField,const QString& whereClause);

    /*returns the ID of an entry which occurs at first*/
    int getPrimaryKey(const QString& table,const QString& lookUpField,const QString& lookUpValue);

    bool containsField(const QString& table, const QString& field);
    bool containsValue(const QString& table, const QString& field, const QString& val);
    bool containsValue(const QString &table, const QString &field, const QStringList &vals);
signals:

public slots:

private:
    QSqlDatabase database,db2;

    QList<QMap<QString, QVariant> > getFieldMap(const QStringList &fields, QSqlQuery query);

    void error(const QSqlQuery& q,const QString& funcName=QString());
    void error(const QSqlDatabase& db, const QString& funcName=QString());
};

#endif // DB_H
